package com.xiaoma.controller;

import com.xiaoma.config.config.RedisCaCheRepository;
import com.xiaoma.lock.Locker;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.redisson.api.RAtomicDouble;
import org.redisson.api.RCountDownLatch;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
@RequestMapping("/api/redis")
public class RedisController {

//    @Autowired
    private RedisCaCheRepository redisService;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RSemaphore semaphore;

    @Autowired
    private RCountDownLatch countDownLatch;

    @Autowired
    private Locker locker;

    @Resource(name = "stringRedisTemplate")
    private StringRedisTemplate stringRedisTemplate;
    
    
    @RequestMapping(path = "/test", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public String test(){
        String lockKey = "localKey";
        String value = "localKey";
        boolean result = redisService.setNx("localKey", "value");
        
        stringRedisTemplate.opsForValue().set(lockKey, value, 1, TimeUnit.MINUTES);// 设置key
                                                                                   // 和过期时间原子操作
        // true 设置成功
        
        if(!result){
            return "error_code";
        }
        
        // dosomething
        /**
         * 1、抛异常没有删除锁，放try catch，在finally中删除锁
         * 2、有可能宕机，也不会删除锁
         * 3、key设置过期时间，即使宕机锁也会失效的。
         * 4、第一个线程加锁可能被第二个线程删除掉.删除时判断value是不是我自己设置的
         */
        redisService.deleteKey(lockKey);
        return "add successfuly";
    }

    @RequestMapping(path = "/lock", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public String lock(){
        RAtomicDouble myDouble = locker.getAtomicDouble("myDouble");
        double andIncrement = myDouble.getAndIncrement();
        System.out.println(andIncrement);
        return "lock successfuly";
    }

    @RequestMapping(path = "/semaphore", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public String semaphore() throws InterruptedException {
        //分布式信号量
        semaphore.acquire();
        System.out.println(System.currentTimeMillis()+Thread.currentThread().getName()+"获取到锁");
        Thread.sleep(1000);
        System.out.println("执行业务................");
        semaphore.release();
        System.out.println(System.currentTimeMillis()+Thread.currentThread().getName()+"释放锁");
        System.out.println("执行完毕。。。。。。。");
        return " successfuly";
    }

    @RequestMapping(path = "/countdown", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public String countdown() throws InterruptedException {
        System.out.println("等待全部执行完毕");
        countDownLatch.await();
        return "全部执行完毕";
    }

    @RequestMapping(path = "/gohome", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public String goHome() throws InterruptedException {
        countDownLatch.countDown();
        return "执行完毕";
    }
}